<?php

/*
 * Camelot PHP Tools
 *
 * @version 2.0
 * @author Bendsoft
 * @package PHP Tools
 * @subpackage Camelot
 * @license FreeBSD License (www.bendsoft.com/licensing/)
 * 
 */

/**
 * Command object for a SharePointSqlQuery. This command object executes the 
 * ExecuteCamelotXML method in the Camelot SharePoint Integration Service
 * @author Bendsoft
 */
class SharePointSqlCommand extends SharePointCommandBase {

    /**
     * Send sql command (this is a greedy argument, if set it will disable the listName property)
     * @var string
     */
    public $sql;

    /**
     * 
     * @param string $connection_name Name of the connection
     * @param string $sql Send sql command (this is a greedy argument, if set it will disable the listName property)
     * @param string $contentType Select items of a specific content type
     * @param bool $includeAttachments Currently not implemented (default false)
     */
    public function __construct($connection_name = null, $sql = null, $includeAttachments = false) {
        parent::__construct();
        $this->connection_name = $connection_name;
        $this->sql = $sql;
        $this->includeAttachments = $includeAttachments;
    }

    /**
     * Build the command from an array for backwards compatibility
     * @param array $args
     */
    public function buildCommandFromArray($args) {
        if (CamelotExtensions::getVariableType($args) == "array") {
            $this->connection_name = array_key_exists('connection_name', $args) ? $args['connection_name'] : null;
            $this->sql = array_key_exists('sql', $args) ? $args['sql'] : null;
            $this->includeAttachments = array_key_exists('includeAttachments', $args) ? $args['includeAttachments'] : null;
        }
    }

    /**
     * Validate a SharePointSqlCommand
     * @param SharePointSqlCommand $command
     * @return CamelotException|boolean
     */
    public function isValid(SharePointSqlCommand $command = null) {
        // Set $command as the current instace if $command is null and the instance is set
        if ($command == null && isset($this)) {
            $command = $this;
        }

        // Validate the connection name
        if (empty($command->connection_name)) {
            return new CamelotException(null, 406);
        }

        if (empty($command->sql)) {
            return new CamelotException(null, 401);
        }

        // If all is OK
        return true;
    }

    /**
     * Execute a SharePointSqlCommand
     * @param SharePointSqlCommand $command
     * @return CamelotSoapClient|CamelotException
     */
    public function execute(SharePointSqlCommand $command = null) {
        // Set $command as the current instace if $command is null and the instance is set
        if ($command == null && isset($this)) {
            $command = $this;
        }

        
        // Get the WcfSettingsObject
        $WcfSettingsList = WcfSettingsList::instance();
        $settings = $WcfSettingsList->getSettings($command->connection_name);

        if ($settings instanceof WcfSettingsObject) {

            // Get any cached file
            $download = $this->get_cached_file($settings);

            // If no cached file or if the download resulted in an exception (ensure data connectivity first)
            if (is_null($download) || $download instanceof CamelotException) {
                $client = new CamelotSoapClient($settings);

                // If we have an error, return the client with all exception details
                if ($client->commandStatus === false) {
                    return $client;
                }

                $args = array(
                    'compression' => $settings->compression,
                    'connectionString' => $settings->connection_string,
                    'sharedKey' => $settings->wsdl_shared_key,
                    'sql' => $command->sql
                );

                try {
                    $response = $client->client->ExecuteCamelotXML($args);

                    if (is_null($response)) {
                        return new CamelotException(null, 411);
                    } else {
                        $download = $response->ExecuteCamelotXmlResult;
                    }

                    // Update the cached file (if required)
                    $cacheResult = $this->set_cached_file($download, $settings);

                    if ($cacheResult instanceof CamelotException) {
                        // TODO, Caching failed
                    }
                } catch (SoapFault $exc) {
                    return new CamelotException($exc);
                }
            }

            if ($settings->compression == 1 || $settings->compression == true || $settings->compression == "true") {
                $download = $this->decode_packet($download);

                if ($download instanceof CamelotException) {
                    return $download;
                }
            }

            $camelotXml = new CamelotXmlReader();
            $packet = $camelotXml->get_list_data($download, 1, null);
            return $packet;
        } else {
            return new CamelotException(null, 800);
        }
    }

}

?>
